package com.github.zly2006.icujavasdk;

import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

public class Account {
    Map<String, List<Predicate<Packet>>> eventRegistry = new HashMap<>();

    public void disconnect() {

    }

    /**
     * @param id             the unique id of the user, this argument also accepts other identify ways like phone number.
     * @param passwordHashed hashed password.
     * @param onOpen         called when connecting to the server.
     * @param onError        called when an error happened. if you want to close the client, return true, Otherwise, return false.
     * @param onClose        called when disconnect.
     */
    public Account(URI serverUri, long id, String passwordHashed, Runnable onOpen, Predicate<Integer> onError, Runnable onClose) {
        this.id = id;
        this.password = passwordHashed;
        webSocket = new WebSocketClient(serverUri) {
            @Override
            public void onOpen(ServerHandshake serverHandshake) {
                onOpen.run();
            }

            @Override
            public void onMessage(String s) {
                if (s.startsWith("Error\n")) {
                    if (onError.test(Integer.parseInt(s.substring(s.indexOf('\n') + 1, s.indexOf("\n\n") - s.indexOf('\n') - 1))))
                    {
                        disconnect();
                    }
                } else {
                    Packet packet = new Packet(s);
                    if (eventRegistry.containsKey(packet.method)) {
                        for (int i = 0; i < eventRegistry.size(); i++) {
                            if (eventRegistry.get(packet.method).get(i).test(packet)) {
                                eventRegistry.get(packet.method).remove(i);
                                i--;
                            }
                        }
                    }
                }
            }

            @Override
            public void onClose(int i, String s, boolean b) {

            }

            @Override
            public void onError(Exception e) {

            }
        }
    }

    public boolean login(String joinKey) {
        webSocket.send("Login\n%d\n%s\n%s\n\n".formatted(id, password, joinKey));

    }

    public boolean login() {
        webSocket.send("Login\n%d\n%s\n\n".formatted(id, password));
    }

    public enum State {
        Initialized,
        Connecting,
        Online,
        Offline,
        Closed
    }

    private State status;
    final private long id;
    final private String password;
    WebSocket webSocket;
}
